/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "pch.h"
#include "LLVM_JIT.h"
#include <llvm-c/Core.h>


#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include <llvm/IRReader/IRReader.h>

#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/CommandLine.h>
 
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include "llvm/IR/Verifier.h"

#include <llvm/ADT/StringRef.h>

#include <llvm/ExecutionEngine/JITSymbol.h>
#include <llvm/ExecutionEngine/Orc/CompileUtils.h>
#include <llvm/ExecutionEngine/Orc/Core.h>


#include <llvm/ExecutionEngine/GenericValue.h>
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/DerivedTypes.h"

#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"

#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"




#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include <algorithm>
#include <cassert>

static llvm::ExitOnError ExitOnErr;




static llvm::LLVMContext g_环境;
static std::unique_ptr<llvm::Module> g_模块 = nullptr;
static llvm::Module* g_模块p = nullptr;
static std::unique_ptr<llvm::FunctionPassManager> IR代码优化管理器;
static llvm::ExecutionEngine* g_构建引擎 = nullptr;
static llvm::RTDyldMemoryManager* RTDyldMM = nullptr;

//static llvm::DataLayout g_数据布局 = std::make_unique<llvm::KaleidoscopeJIT>();
//llvm::TargetMachine* target_machine = target_info->createTargetMachine(real_triple, "", "", options, reloc_model);

static llvm::IRBuilder<> g_Builder(g_环境);
//static std::unique_ptr<llvm::KaleidoscopeJIT> TheJIT = std::make_unique<llvm::KaleidoscopeJIT>();
//llvm::ModulePass;

/*
llvm::AllocaInst* memory =
	builder.CreateAlloca(int8_type, builder.getInt32(MEMORY_SIZE), "memory");
builder.CreateMemSet(memory, builder.getInt8(0), MEMORY_SIZE, 1);
llvm::AllocaInst* dataptr_addr =
	builder.CreateAlloca(int32_type, nullptr, "dataptr_addr");
builder.CreateStore(builder.getInt32(0), dataptr_addr);




for (size_t pc = 0; pc < program.instructions.size(); ++pc) {
  char instruction = program.instructions[pc];
  switch (instruction) {
  case '>': {
	llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
	llvm::Value* inc_dataptr =
		builder.CreateAdd(dataptr, builder.getInt32(1), "inc_dataptr");
	builder.CreateStore(inc_dataptr, dataptr_addr);
	break;
  }
  case '<': {
	llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
	llvm::Value* dec_dataptr =
		builder.CreateSub(dataptr, builder.getInt32(1), "dec_dataptr");
	builder.CreateStore(dec_dataptr, dataptr_addr);
	break;
  }
 }




case '+': {
  llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
  llvm::Value* element_addr =
	  builder.CreateInBoundsGEP(memory, {dataptr}, "element_addr");
  llvm::Value* element = builder.CreateLoad(element_addr, "element");
  llvm::Value* inc_element =
	  builder.CreateAdd(element, builder.getInt8(1), "inc_element");
  builder.CreateStore(inc_element, element_addr);
  break;
}
case '-': {
  llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
  llvm::Value* element_addr =
	  builder.CreateInBoundsGEP(memory, {dataptr}, "element_addr");
  llvm::Value* element = builder.CreateLoad(element_addr, "element");
  llvm::Value* dec_element =
	  builder.CreateSub(element, builder.getInt8(1), "sub_element");
  builder.CreateStore(dec_element, element_addr);
  break;
}




case '.': {
  llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
  llvm::Value* element_addr =
	  builder.CreateInBoundsGEP(memory, {dataptr}, "element_addr");
  llvm::Value* element = builder.CreateLoad(element_addr, "element");
  llvm::Value* element_i32 =
	  builder.CreateIntCast(element, int32_type, false, "element_i32_");
  builder.CreateCall(putchar_func, element_i32);
  break;
}
case ',': {
  llvm::Value* user_input =
	  builder.CreateCall(getchar_func, {}, "user_input");
  llvm::Value* user_input_i8 =
	  builder.CreateIntCast(user_input, int8_type, false, "user_input_i8_");
  llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
  llvm::Value* element_addr =
	  builder.CreateInBoundsGEP(memory, {dataptr}, "element_addr");
  builder.CreateStore(user_input_i8, element_addr);
  break;


  case '[': {
  llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
  llvm::Value* element_addr =
	  builder.CreateInBoundsGEP(memory, {dataptr}, "element_addr");
  llvm::Value* element = builder.CreateLoad(element_addr, "element");
  llvm::Value* cmp =
	  builder.CreateICmpEQ(element, builder.getInt8(0), "compare_zero");

  llvm::BasicBlock* loop_body_block =
	  llvm::BasicBlock::Create(context, "loop_body", jit_func);
  llvm::BasicBlock* post_loop_block =
	  llvm::BasicBlock::Create(context, "post_loop", jit_func);
  builder.CreateCondBr(cmp, post_loop_block, loop_body_block);
  open_bracket_stack.push(BracketBlocks(loop_body_block, post_loop_block));
  builder.SetInsertPoint(loop_body_block);
  break;
}
case ']': {
  if (open_bracket_stack.empty()) {
	DIE << "unmatched closing ']' at pc=" << pc;
  }
  BracketBlocks blocks = open_bracket_stack.top();
  open_bracket_stack.pop();

  llvm::Value* dataptr = builder.CreateLoad(dataptr_addr, "dataptr");
  llvm::Value* element_addr =
	  builder.CreateInBoundsGEP(memory, {dataptr}, "element_addr");
  llvm::Value* element = builder.CreateLoad(element_addr, "element");
  llvm::Value* cmp =
	  builder.CreateICmpNE(element, builder.getInt8(0), "compare_zero");
  builder.CreateCondBr(cmp, blocks.loop_body_block, blocks.post_loop_block);
  builder.SetInsertPoint(blocks.post_loop_block);
  break;
}

*/



/*
1 llvm:: Function* createKernel(int numberOfParameters){
2 std::vector <llvm::Type *> kernel_arg_types;
3 for(int i = 0; i < numberOfParameters; i++){
49
4 kernel_arg_types.push_back(llvm::Type:: getFloatPtrTy(
,→ context , 1));
5 }
6
7 auto kernel = llvm:: Function :: Create(
8 llvm:: FunctionType ::get(llvm::Type:: getVoidTy(context),
,→ kernel_arg_types , false),
9 llvm:: Function :: ExternalLinkage ,
10 llvm::Twine("kernel"),
11 &module
12 );
13
14 kernel ->setCallingConv(llvm:: CallingConv :: PTX_Kernel);
15
16 return kernel;
17 }
*/

//#include "D:\DEV\LLVM-main\llvm\lib\Target\X86\TargetInfo\X86TargetInfo.h"



S_LLVM模块::S_LLVM模块() : m_Builder(g_环境)
{
	auto TargetTriple = llvm::sys::getDefaultTargetTriple();

	std::string Error;

	llvm::TargetOptions opt;
	auto Target = llvm::TargetRegistry::lookupTarget(TargetTriple, Error);
	auto CPU = llvm::sys::getHostCPUName();
	auto Features = "";// llvm::sys::getHostCPUFeatures
	auto RM = llvm::Optional<llvm::Reloc::Model>();
	auto TheTargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);


	m_模块_愚蠢的需求设计.reset(new llvm::Module("my module", g_环境));
	m_模块_愚蠢的需求设计->setTargetTriple(TargetTriple);
	m_模块_愚蠢的需求设计->setDataLayout(TheTargetMachine->createDataLayout());

	m_模块 = m_模块_愚蠢的需求设计.get();
}

void f_llvm_卸载程序(S_LLVM模块* model)
{
	model->m_运行引擎->removeModule(model->m_模块);
	
}




//bool f_llvm_初始化JIT引擎(std::unique_ptr<llvm::Module> 模块) {
bool f_llvm_初始化JIT引擎() {
	auto TargetTriple = llvm::sys::getDefaultTargetTriple();
	//llvm::InitializeLlvmTargetIfNeeded();
	//initializeLlvmPassRegistryIfNeeded();
	//LLVMInitializeNVPTXTargetAsmPrinter();

	llvm::InitializeNativeTarget();
	llvm::InitializeNativeTargetAsmPrinter();
	llvm::InitializeNativeTargetAsmParser();

	//auto Target_GPU = llvm::TargetRegistry::lookupTarget("nvptx64-nvidia-cuda", Error);
	//auto& Target = llvm::getTheX86_64Target();
	//llvm::Triple triple(llvm::Twine("NVPTX"));
	//std::string arch("nvptx64-nvidia-cuda");
	//auto t = llvm::TargetRegistry::lookupTarget("nvptx64-nvidia-cuda", Error);
	//const llvm::Target* target(llvm::TargetRegistry::lookupTarget(arch, Error));
	//llvm::CUdevice device;
	//llvm::CUcontext context;
	return true;


	std::string Error;
	auto Target = llvm::TargetRegistry::lookupTarget(TargetTriple, Error);
	//auto CPU = "generic"; 
	auto CPU = llvm::sys::getHostCPUName();
	auto Features = "";// llvm::sys::getHostCPUFeatures
	llvm::TargetOptions opt;
	auto RM = llvm::Optional<llvm::Reloc::Model>();
	auto TheTargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
	

	
	std::string err;
	//llvm::StringRef real_triple = m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple();
	//const llvm::Target* target_info = llvm::TargetRegistry::lookupTarget(real_triple, err);
	if (g_模块 == nullptr) {
		//llvm::DataLayout DL("m:w-p:64:64"); // macho
		g_模块.reset(new llvm::Module("my module", g_环境));
		g_模块->setTargetTriple(TargetTriple);
		g_模块->setDataLayout(TheTargetMachine->createDataLayout());

		g_模块p = g_模块.get();
	}

	return true;
}

bool f_llvm_清理JIT引擎() {
	//LLVMDisposeExecutionEngine(g_构建引擎);
	return false;
}


void f_llvm_构建机器码() {
	//auto jit = ExitOnErr(llvm::orc::KaleidoscopeJIT::Create());
	std::vector<llvm::Type*> args;
	
	llvm::FunctionType* pFuncType = llvm::FunctionType::get(llvm::Type::getDoubleTy(g_环境), args, false);
	llvm::Function* pFunc = llvm::Function::Create(pFuncType, llvm::Function::ExternalLinkage, "函 数", g_模块.get());
	//auto f = g_模块.get()->getFunction("函 数");
	
	llvm::BasicBlock* pBlock = llvm::BasicBlock::Create(g_环境, "entry", pFunc);
	g_Builder.SetInsertPoint(pBlock);

	llvm::Value* pV1 = llvm::ConstantFP::get(g_环境, llvm::APFloat(1.01));
	llvm::Value* pV2 = llvm::ConstantFP::get(g_环境, llvm::APFloat(1.01));
	llvm::Value* pRetVal = g_Builder.CreateFAdd(pV1, pV2, "addtmp");

	g_Builder.CreateRet(pRetVal);
	bool 是否有错误 = verifyFunction(*pFunc);
	//IR代码优化管理器->run(*pFunc);

	//pFunc->eraseFromParent();
	std::string 错误信息;
	

	g_构建引擎 = llvm::EngineBuilder(std::move(g_模块))
		.setEngineKind(llvm::EngineKind::JIT)
		.setErrorStr(&错误信息)
		.setVerifyModules(true)
		//.setEngineKind(llvm)
		.setMCJITMemoryManager(std::unique_ptr<llvm::RTDyldMemoryManager>(RTDyldMM))
		.setOptLevel(llvm::CodeGenOpt::Default)
		.create();

	//g_构建引擎->addModule();
	//pFunc->dump();
	auto f = g_构建引擎->getFunctionAddress("函 数");
	//std::cout << g_Builder << std::endl;
}

llvm::LLVMContext& f_llvm_构建环境() {
	return g_环境;
}

llvm::Module* f_llvm_模块() {
	return g_模块p;
}

uint32 f_llvm_创建程序集()
{
	S_LLVM模块* model = new S_LLVM模块();

	return uint32();
}


static std::set<llvm::Module*> g_程序块;

llvm::Module* f_llvm_创建程序集(const std::string& path) {
	std::string 错误信息;
	llvm::SMDiagnostic err;

	llvm::Module* mp = nullptr;
	if (g_构建引擎) {
		std::unique_ptr<llvm::Module> m = llvm::parseIRFile((path), err, g_环境);
		mp = m.get();

		g_构建引擎->addModule(std::move(m));
	}
	else {
		std::unique_ptr<llvm::Module> m = llvm::parseIRFile((path), err, g_环境);
		mp = m.get();

		g_构建引擎 = llvm::EngineBuilder(std::move(m))
			.setEngineKind(llvm::EngineKind::JIT)
			.setErrorStr(&错误信息)
			.setVerifyModules(true)
			//.setEngineKind(llvm)
			.setMCJITMemoryManager(std::unique_ptr<llvm::RTDyldMemoryManager>(RTDyldMM))
			.setOptLevel(llvm::CodeGenOpt::Default)
			.create();
	}

	//std::unique_ptr<llvm::Module> m = llvm::getLazyIRFileModule(f_StringToUTF8(path), err, g_环境);
	//std::unique_ptr<llvm::Module> ma = llvm::parseIRFile(f_StringToUTF8(path), err, g_环境);
	//mp = m.get();
	//g_构建引擎->generateCodeForModule(std::move(ma).get());
	//mp = ma.get();
	//g_构建引擎->addModule(std::move(m));
	//bool 删除模块 = g_构建引擎->removeModule(mp);
	
	g_程序块.insert(mp);
	return mp;
}

void f_llvm_销毁程序集(llvm::Module* module) {
	if(!g_构建引擎) return;

	bool 删除模块 = g_构建引擎->removeModule(module);
	if (!删除模块) {
		std::cout<<"删除JIT模块失败"<<std::endl;
	}
	g_程序块.erase(module);
}

uint64 f_llvm_从程序集取函数指针(const std::string& funName) {
	uint64 fuc = 0;

	fuc = g_构建引擎->getFunctionAddress(funName);
	//C++函数指针注册为LLVM中的全局变量。
	return fuc;
}

bool f_llvm_执行函数(const std::string& funName, llvm::ExecutionEngine* 执行引擎, std::vector<E_JIT_FunParam>& 参数) {
	llvm::Function* func = 执行引擎->FindFunctionNamed(funName);
	std::vector<llvm::GenericValue> args;

	int32 n = 1;
	for (auto& e : 参数) {
		auto gv = llvm::GenericValue(NULL);
		//gv.PointerVal = &e;
		gv.IntVal = llvm::APInt(64, (uint64)&e, true);
		args.push_back(gv);
	}
	//参数.FloatVal = 1.0;
	//参数.PointerVal = nullptr;
	//args.push_back(llvm::GenericValue(NULL));
	llvm::GenericValue v = 执行引擎->runFunction(func, args);
	return v.IntVal.getBoolValue();
}

void f_llvm_添加全局变量(const std::string& 全局变量名称, uint64 全局变量值) {
	g_构建引擎->addGlobalMapping(全局变量名称, 全局变量值);
}






llvm::Value* f_llvm_构建i8变量(llvm::LLVMContext& ctx, llvm::BasicBlock* block, int32 初始值, std::string 名称)
{
	llvm::Type* tp = llvm::Type::getInt8Ty(ctx);
	auto name = llvm::Twine(名称);
	return  new llvm::AllocaInst(tp, 0, name, block);
}

llvm::Value* f_llvm_构建i16变量(llvm::LLVMContext& ctx, llvm::BasicBlock* block, int32 初始值, std::string 名称)
{
	llvm::Type* tp = llvm::Type::getInt16Ty(ctx);
	auto name = llvm::Twine(名称);
	return  new llvm::AllocaInst(tp, 0, name, block);
}

llvm::Value* f_llvm_构建i32变量(llvm::LLVMContext& ctx, llvm::BasicBlock* block, int32 初始值, std::string 名称)
{
	llvm::Type* tp = llvm::Type::getInt32Ty(ctx);
	auto name = llvm::Twine(名称);
	return  new llvm::AllocaInst(tp, 0, name, block);
}

llvm::Value* f_llvm_构建变量(llvm::LLVMContext& ctx, llvm::BasicBlock* block, E_值类型 type, int64 初始值, bool 是否有符合)
{
	std::string name;
	llvm::Type* tp = f_llvm_构建类型(ctx, type, name);
	
	if (block) {
		return new llvm::AllocaInst(tp, 0, name, block);
	}
	return new llvm::GlobalVariable(tp, false, llvm::GlobalValue::CommonLinkage);
	
}

llvm::Type* f_llvm_构建类型(llvm::LLVMContext& ctx, E_值类型 type, std::string& name)
{
	llvm::Type* tp = nullptr;
	switch (type)
	{
	case e_Type_None:
		break;
	case e_Type_Enum:
		break;
	case e_Type_Bool:
		break;
	case e_Type_F32:
		name = "f";
		tp = llvm::Type::getFloatTy(ctx);
		break;
	case e_Type_F64:
		name = "f";
		tp = llvm::Type::getDoubleTy(ctx);
		break;
	case e_Type_F64_1D:
		break;

	case e_Type_UI8:
		name = "u";
	case e_Type_I8:
		tp = llvm::Type::getInt8Ty(ctx);
		break;

	case e_Type_UI16:
		name = "u";
	case e_Type_I16:
		tp = llvm::Type::getInt16Ty(ctx);
		break;

	case e_Type_UI32:
		name = "u";
	case e_Type_I32:
		tp = llvm::Type::getInt32Ty(ctx);
		break;

	case e_Type_UI64:
		name = "u";
	case e_Type_I64:
		tp = llvm::Type::getInt64Ty(ctx);
		break;

	case e_Type_Vec2:
		break;
	case e_Type_Vec3:
		break;
	case e_Type_Vec4:
		break;
	case e_Type_iVec2:
		break;
	case e_Type_uVec2:
		break;
	case e_Type_iVec3:
		break;
	case e_Type_uVec3:
		break;
	case e_Type_iVec4:
		break;
	case e_Type_uVec4:
		break;
	case e_Type_Mat2X2:
		break;
	case e_Type_Mat3X3:
		break;
	case e_Type_Mat4X4:
		break;
	case e_Type_图像:
		break;
	case e_插座Type_ArrayBegin:
		break;
	case e_Type_Str_1D:
		break;
	case e_插座Type_Str_2D:
		break;
	case e_插座Type_Str_3D:
		break;
	case e_插座Type_Str_4D:
		break;
	case e_Type_Bool_Array1D:
		break;
	case e_插座Type_Array2D_Bool:
		break;
	case e_插座Type_Array3D_Bool:
		break;
	case e_Type_UI32_FlagBits:
		break;
	case e_Type_I8_1D:
		break;
	case e_插座Type_I8_Array2D:
		break;
	case e_Type_Bool_1D:
		break;
	case e_插座Type_I8_Array4D:
		break;
	case e_Type_F32_Array1D:
		break;
	case e_插座Type_F32_Array2D:
		break;
	case e_插座Type_F32_Array3D:
		break;
	case e_插座Type_Array4D_F32:
		break;
	case e_Type_I32_1D:
		break;
	case e_插座Type_I32_Array2D:
		break;
	case e_插座Type_I32_Array3D:
		break;
	case e_插座Type_I32_Array4D:
		break;
	case e_Type_UI32_1D:
		break;
	case e_插座Type_UI32_Array2D:
		break;
	case e_插座Type_UI32_Array3D:
		break;
	case e_插座Type_UI32_Array4D:
		break;
	case e_Type_I64_Array1D:
		break;
	case e_插座Type_I64_Array2D:
		break;
	case e_插座Type_I64_Array3D:
		break;
	case e_插座Type_I64_Array4D:
		break;
	case e_插座Type_UI64_Array1D:
		break;
	case e_Type_Vec2_Array1D:
		break;
	case e_插座Type_Vec2_Array2D:
		break;
	case e_插座Type_Vec2_Array3D:
		break;
	case e_Type_Vec2_1D:
		break;
	case e_Type_Vec3_Array1D:
		break;
	
	case e_插座Type_Vec3_Array4D:
		break;
	case e_Type_UI32_2D:
		break;
	case e_插座Type_uVec3_Array2D:
		break;
	case e_插座Type_uVec3_Array3D:
		break;
	case e_插座Type_uVec3_Array4D:
		break;
	case e_Type_Vec4_Array1D:
		break;
	case e_插座Type_Vec4_Array2D:
		break;
	case e_插座Type_Vec4_Array3D:
		break;
	case e_插座Type_Vec4_Array4D:
		break;
	case e_Type_iVec2_1D:
		break;
	case e_插座Type_Vec2i_Array2D:
		break;
	case e_过程纹理:
		break;
	case e_过程纹理_1D:
		break;
	case e_插座Type_Vec3i_Array1D:
		break;
	case e_插座Type_Vec3i_Array2D:
		break;
	case e_插座Type_Vec3i_Array3D:
		break;
	case e_Type_Shader:
		break;
	case e_Type_Node:
		break;
	case e_Type_Widget:
		break;
	case e_Type_TexProp:
		break;
	case e_Type_Quat:
		break;
	case e_Type_Quat_Array1D:
		break;
	case e_插座Type_Rect32f:
		break;
	case e_插座Type_Rect32f_Array1D:
		break;
	case e_插座Type_Vec球:
		break;
	case e_Type_VecSphere_1D:
		break;
	case e_插座Type_Mat2X2_Array1D:
		break;
	case e_插座Type_Mat3X3_Array1D:
		break;
	case e_Type_Mat4X4_Array1D:
		break;

	case e_插座Type_Mat4X4_Array3D:
		break;
	case e_插座Type_Mat4X4_Array4D:
		break;
	case e_插座Type_八叉树:
		break;
	case e_Type_End:
		break;
	default:
		break;
	}
	return tp;
}

llvm::AllocaInst* f_llvm_构建f32变量(llvm::LLVMContext& ctx, llvm::BasicBlock* block, int32 初始值)
{
	llvm::Type* tp = llvm::Type::getFloatTy(ctx);
	auto name = llvm::Twine("");
	return  new llvm::AllocaInst(tp, 0, name, block);
}

S_函数IR块 f_llvm_构建函数声明(std::string name, std::vector<llvm::Type*>& 参数类型, llvm::Type* 返回类型, bool 是否有常量)
{
	llvm::FunctionType* pFuncType = llvm::FunctionType::get(llvm::Type::getVoidTy(f_llvm_构建环境()), 参数类型, false);
	llvm::Function* pFunc = llvm::Function::Create(pFuncType, llvm::Function::ExternalLinkage, name, f_llvm_模块());

	llvm::BasicBlock* pBlock = llvm::BasicBlock::Create(g_环境, "entry", pFunc);
	g_Builder.SetInsertPoint(pBlock);


	return { pFunc, pBlock };
}

void f_llvm_构建返回值(S_函数IR块& block, llvm::Value* pRetVal, std::string 函数名称) {
	//g_Builder.SetInsertPoint(block.pBlock);
	g_Builder.CreateRet(pRetVal);


	bool 是否有错误 = verifyFunction(*block.pFunc);
	//block.pFunc->eraseFromParent();
	//block.pFunc->dump();



	std::string 错误信息;
	if (nullptr == g_构建引擎) {
		RTDyldMM = new llvm::SectionMemoryManager();

		g_构建引擎 = llvm::EngineBuilder(std::move(g_模块))
			//.setTargetOptions
			//.setMArch("x86-64")
			.setEngineKind(llvm::EngineKind::JIT)
			.setErrorStr(&错误信息)
			.setVerifyModules(false)
			.setMCJITMemoryManager(std::unique_ptr<llvm::RTDyldMemoryManager>(RTDyldMM))
			.setOptLevel(llvm::CodeGenOpt::Default)
			.create();

	}
	else {
		g_构建引擎->addModule(std::move(g_模块));

	}


	auto fu = g_构建引擎->getFunctionAddress(函数名称);

}

//unsigned



/*ExecutionEngine* pExecutor =
		EngineBuilder(&module).setErrorStr(&sError).create();
	if (!pExecutor) {
		fprintf(stderr, "Creating ExecutionEngine error: %s\n", sError.c_str());
		exit(EINVAL);
	}
*/


/*
* 
* 	IRBuilder<> builder(context);
 
	//Create a function type without params.
	std::vector<Type*> args;
	FunctionType *pFuncType = FunctionType::get(
		Type::getDoubleTy(context), args, false);
 
	//Create a function with external linkage.
	Function *pFunc = Function::Create(
		pFuncType, Function::ExternalLinkage, "Foo", &module);
 
	// Create the entry basic block.
	BasicBlock *pBlock = BasicBlock::Create(context, "entry", pFunc);
	builder.SetInsertPoint(pBlock);
 
	//Generate the codes: nArg1 + nArg2.
	Value *pV1 = ConstantFP::get(context, APFloat(nArg1));
	Value *pV2 = ConstantFP::get(context, APFloat(nArg2));
	Value *pRetVal = builder.CreateFAdd(pV1, pV2, "addtmp");
	if (!pRetVal) {
		// Error reading body, remove function.
		pFunc->eraseFromParent();
		std::cerr << "Reading function body error.\n";
		return ENOENT;
	}

		// Finish off the function.
	builder.CreateRet(pRetVal);

	// Validate the generated code, checking for consistency.
	verifyFunction(*pFunc);

	pFunc->dump();

	// JIT the function, returning a function pointer.
	void *pJITFunc = pExecutor->getPointerToFunction(pFunc);

	// Cast it to the right type (takes no arguments, returns a double) so we
	// can call it as a native function.
	double (*pf)() = (double (*)())(intptr_t)pJITFunc;

* 
*/



/*

typedef void (*func_type)(void*);

// path是bc文件的路径，func_name是要执行的函数名
void Run(const std::string& path, const std::string& func_name) {

	// 首先要读取要执行的bc字节码
	SMDiagnostic error;
	std::unique_ptr<Module> Owner = parseIRFile(path, error, context);
	if(Owner == nullptr) {
		cout << "Load Error: " << path << endl;
		Owner->dump();
		return;
	}

	// 单例的方法进行初始化，暂未考虑多线程
	initEE(std::move(Owner));


	getPointerToNamedFunction()
	// 获取编译后的函数指针并执行
	uint64_t func_addr = EE->getFunctionAddress(func_name.c_str());
	if (func_addr == 0) {
		printf("错误, 找不到函数: %s\n", func_name.c_str());
		return;
	}
	func_type func = (func_type) func_addr;
	func(NULL); // 需要传参数时可以从这里传递
}



// 给解释器使用的部分
Function* func = EE->FindFunctionNamed(func_name.c_str());
if (func == NULL) {
	printf("忽略, 找不到函数: %s\n", func_name.c_str());
	return;
}
// 如果需要传参数的话
std::vector<GenericValue> args;
args.push_back(GenericValue(NULL));
EE->runFunction(func, args);



*/





llvm::Value* f_llvm_构建算术运算符L1IR(const std::vector<S_操作符表达段>& 运算符)
{
	uint32 num = 运算符.size();

	for (auto& e : 运算符) {
		if (e.操作符名称.empty() == false) {

		}
	}



	return nullptr;
}

llvm::Value* f_llvm_构建算术运算符L1IR(llvm::Value* 计算数, E_运算符 op)
{
	//auto name = 计算数->getName();
	switch (op) {
	case E_运算符::e_非:
		return g_Builder.CreateNot(计算数);
	case E_运算符::e_按位取反:
		return g_Builder.CreateNeg(计算数);
	case E_运算符::e_前加加:
		return g_Builder.CreateAdd(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	case E_运算符::e_前减减:
		return g_Builder.CreateSub(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	default:
		break;
	}

	return nullptr;
}

llvm::Value* f_llvm_构建算术运算符L2IR(llvm::Value* 计算数, E_运算符 op)
{
	switch (op) {
	case E_运算符::e_非:
		return g_Builder.CreateNot(计算数);
	case E_运算符::e_按位取反:
		return g_Builder.CreateNeg(计算数);
	case E_运算符::e_前加加:
		return g_Builder.CreateAdd(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	case E_运算符::e_前减减:
		return g_Builder.CreateSub(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	default:
		break;
	}
	return nullptr;
}

llvm::Value* f_llvm_构建算术运算符L3IR(llvm::Value* 计算数, E_运算符 op)
{
	switch (op) {
	case E_运算符::e_后加加:
		return g_Builder.CreateNot(计算数);
	case E_运算符::e_后减减:
		return g_Builder.CreateNeg(计算数);
	case E_运算符::e_取指针:
		return g_Builder.CreateAdd(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	case E_运算符::e_类型转换:
		return g_Builder.CreateSub(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	case E_运算符::e_类型大小:
		return g_Builder.CreateSub(计算数, llvm::ConstantFP::get(g_环境, llvm::APFloat(1.0)));
	}
	return nullptr;
}

llvm::Value* f_llvm_构建算术运算符L5IR(llvm::Value* 计算数, E_运算符 op)
{
	switch (op) {
	case E_运算符::e_乘:
		return g_Builder.CreateNot(计算数);
	case E_运算符::e_除:
		return g_Builder.CreateNeg(计算数);
	}
	return nullptr;
}



llvm::Value* f_llvm_构建乘除运算符IR(llvm::Value* 计算数L, llvm::Value* 计算数R, E_运算符 op)
{
	for (uint32 i = E_运算符优先级区间begin::e_运算符_L6_b; i <= E_运算符优先级区间end::e_运算符_L6_e; ++i) {
		switch (i)
		{
		case E_运算符::e_加:
			return g_Builder.CreateAdd(计算数L, 计算数R);
		case E_运算符::e_减:
			return g_Builder.CreateSub(计算数L, 计算数R);
		}
	}
	return nullptr;
}

llvm::Value* f_llvm_构建加减运算符IR(llvm::Value* 计算数L, llvm::Value* 计算数R, E_运算符 op)
{
	for (uint32 i = E_运算符优先级区间begin::e_运算符_L6_b; i <= E_运算符优先级区间end::e_运算符_L6_e; ++i) {
		switch (i)
		{
		case E_运算符::e_加:
			return g_Builder.CreateAdd(计算数L, 计算数R);
		case E_运算符::e_减:
			return g_Builder.CreateSub(计算数L, 计算数R);
		}
	}
	return nullptr;
}

llvm::Value* f_llvm_构建位移运算符IR(llvm::Value* 计算数L, llvm::Value* 计算数R, E_运算符 op)
{
	for (uint32 i = E_运算符优先级区间begin::e_运算符_L6_b; i <= E_运算符优先级区间end::e_运算符_L6_e; ++i) {
		switch (i)
		{
		case E_运算符::e_左移:
			return g_Builder.CreateShl(计算数L, 计算数R);
		case E_运算符::e_右移:
			return g_Builder.CreateLShr(计算数L, 计算数R);
		}
	}
	return nullptr;
}

llvm::Value* f_llvm_构建赋值运算符IR(llvm::Value* 计算数L, llvm::Value* 计算数R, E_运算符 op)
{
	llvm::Value* temp;
	switch (op) {
	case E_运算符::e_加等于:
		temp = g_Builder.CreateAdd(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_减等于:
		temp = g_Builder.CreateSub(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_乘等于:
		temp = g_Builder.CreateMul(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_除等于:
		if(计算数L->getName() == "u" || 计算数R->getName() == "u") temp = g_Builder.CreateUDiv(计算数L, 计算数R);
		else temp = g_Builder.CreateSDiv(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_余等于:
		if (计算数L->getName() == "u" || 计算数R->getName() == "u") temp = g_Builder.CreateURem(计算数L, 计算数R);
		else temp = g_Builder.CreateSRem(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_左移等于:
		temp = g_Builder.CreateShl(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_右移等于:
		temp = g_Builder.CreateLShr(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_且等于:
		temp = g_Builder.CreateAnd(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_或等于:
		temp = g_Builder.CreateOr(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_异或等于:
		temp = g_Builder.CreateXor(计算数L, 计算数R);
		g_Builder.CreateStore(计算数L, temp);
		break;
	case E_运算符::e_赋值:
		g_Builder.CreateStore(计算数L, 计算数R);
		break;
	}
	
	return nullptr;
}














